//
//  ModelGenerator.m
//  CodeGenerator
//
//  Created by 丁玉松 on 2017/9/12.
//  Copyright © 2017年 Beijing Yingyan Internet Co., Ltd. All rights reserved.
//

#import "ModelGenerator.h"
#import "NSString+FileHandle.h"

@interface DMGDictItem : NSObject
@property (nonatomic ,copy) NSString *className;
@property (nonatomic ,strong) NSDictionary *dict;
@end

@implementation DMGDictItem
@end


@interface ModelGenerator ()

@property (nonatomic, copy) NSString *filePath;

/**
 JsonModel数组
 */
@property (nonatomic ,strong) NSMutableArray *modelArray;

@end

@implementation ModelGenerator

- (instancetype)init
{
    self = [super init];
    if (self) {
        _modelArray = [NSMutableArray new];
    }
    return self;
}

-(void)generateModelWithJsonStr:(NSString *)jsonStr modelName:(NSString *)modelName toTilePath:(NSString *)filePath{

    _filePath = filePath;
    [_modelArray removeAllObjects];
    NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    [self generateModelArray:json key:modelName];
    for (DMGDictItem *item in _modelArray) {
        [self modelInterfaceStr:item.dict modelName:item.className];
        [self modelImpentStr:item.dict modelName:item.className];
    }

}

-(void)generateModelArray:(NSDictionary *)dict key:(NSString *)key{
    DMGDictItem *item = [DMGDictItem new];
    NSMutableString *strkey = (NSMutableString *)[key stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[key substringWithRange:NSMakeRange(0, 1)]uppercaseString]];
    item.className = [NSString stringWithFormat:@"DMG%@Model",strkey];
    item.dict = dict;
    [_modelArray addObject:item];
    
    for (NSString *key in dict.allKeys) {
        
        id ite = [dict objectForKey:key];
        
        if ([ite isKindOfClass:[NSArray class]]) {
            NSArray *array = (NSArray *)ite;
            if (array.count > 0 && [[array firstObject] isKindOfClass:[NSDictionary class]]) {
                NSDictionary *dict2 = [array firstObject];
                [self generateModelArray:dict2 key:[NSString stringWithFormat:@"%@Item",key]];
            }
        }
        
        if ([ite isKindOfClass:[NSDictionary class]]) {
            NSDictionary *dict3 = (NSDictionary *)ite;
            [self generateModelArray:dict3 key:key];
        }
    }
}

#pragma mark -  接口


/**
 Description
 
 @param dict 必须是字典格式
 @param modelName modelName description
 @return return value description
 */
-(NSString *)modelInterfaceStr:(NSDictionary *)dict modelName:(NSString *)modelName{
    
    NSMutableString *respPara = [self propertyDefineString:dict];
    
    NSString *modelStr = [NSString stringWithFormat:
                          @"\
                          \n@interface %@ : YYIDataModel\n\
                          \n%@\
                          \n@end",modelName,respPara];
    [modelStr yyi_writeTofilePath:_filePath anchor:nil];
    return modelStr;
}

-(NSMutableString *)propertyDefineString:(NSDictionary *)dict{
    
    NSMutableString *respPara = [NSMutableString new];
    for (NSString *key in dict.allKeys) {
        id ite = [dict objectForKey:key];
        if ([ite isKindOfClass:[NSArray class]]) {
            [respPara appendString:[NSString stringWithFormat:@"@property (nonatomic, strong) NSArray *%@;\n",key]];
            NSArray *array = (NSArray *)ite;
            if (array.count > 0 && [[array firstObject] isKindOfClass:[NSString class]]) {
                
            }
            
        } else if ([ite isKindOfClass:[NSDictionary class]]) {
            NSMutableString *strkey = (NSMutableString *)[key stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[key substringWithRange:NSMakeRange(0, 1)]uppercaseString]];
            
            NSString *modelClass = [NSString stringWithFormat:@"DMG%@Model",strkey];
            [respPara appendString:[NSString stringWithFormat:@"@property (nonatomic, strong) %@ *%@;\n",modelClass,key]];
        } else {
            [respPara appendString:[NSString stringWithFormat:@"@property (nonatomic, copy) NSString *%@;\n",key]];
        }
    }

    return respPara;
}

#pragma mark - 实现

//对象实现
-(NSString *)modelImpentStr:(NSDictionary *)dict modelName:(NSString *)modelName{
    
    NSString *hier = [self yyi_setModelClassHierarchyWith:dict];
    NSString *svalue = [self yyi_propertyMapWith:dict];//[self yyi_setValueMethodWith:dict];
    NSString *interExt = [self yyi_addInterfaceExtention:dict modelName:modelName];
    NSString *arrayretu = [self yyi_getArray:dict];
    
    NSString *dataImp = [NSString stringWithFormat:
                         @"\
                         \n%@\
                         \n@implementation %@\
                         \n%@\
                         \n%@\
                         \n%@\
                         \n@end\n",interExt,modelName,svalue,hier,arrayretu];
    
    NSString *ocm = [_filePath stringByReplacingCharactersInRange:NSMakeRange(_filePath.length-1, 1) withString:@"m"];
    [dataImp yyi_writeTofilePath:ocm anchor:nil];
    return @"";
}


-(NSString *)yyi_addInterfaceExtention:(NSDictionary *)dict modelName:(NSString *)modelName{
    
    for (NSString *key in dict.allKeys) {
        id ite = [dict objectForKey:key];
        if ([ite isKindOfClass:[NSArray class]]) {
            NSString *interface = [NSString stringWithFormat:
                                   @"\
                                   \n@interface %@ ()\n\
                                   \n@end\n",modelName];
            return interface;
        }
    }
    return @"";
}


-(NSString *)yyi_getArray:(NSDictionary *)dict{
    NSMutableString *hier = [NSMutableString new];
    
    for (NSString *key in dict.allKeys) {
        
        id ite = [dict objectForKey:key];
        if ([ite isKindOfClass:[NSArray class]]) {
            [hier appendString:[NSString stringWithFormat:@"\
                                \n-(NSArray *)%@{\
                                \n  return _%@;\
                                \n}",key,key]];
        }
    }
    return hier;
}

-(NSString *)yyi_setModelClassHierarchyWith:(NSDictionary *)dict{

    NSMutableString *hier = [NSMutableString new];
    
    for (NSString *key in dict.allKeys) {
        
        id ite = [dict objectForKey:key];
        if ([ite isKindOfClass:[NSArray class]]) {
            
            NSMutableString *strkey = (NSMutableString *)[key stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[key substringWithRange:NSMakeRange(0, 1)]uppercaseString]];
            NSString *modelClass = [NSString stringWithFormat:@"DMG%@ItemModel",strkey];
            
            [hier appendString:[NSString stringWithFormat:@"\
                                \n+(id)modelClassHierarchy{\
                                \n  NSDictionary *classHierarchy = @{\
                                \n                                  @\"%@\": @[NSClassFromString(@\"%@\")]\
                                \n                                  };\
                                \n  return classHierarchy;\
                                \n}",key,modelClass]];
        }
    }
    return hier;
}

/**
 setValue:ForKey:

 @param dict dict description
 @return return value description
 */
-(NSString *)yyi_setValueMethodWith:(NSDictionary *)dict{
    NSMutableString *sStr = [NSMutableString new];
    
    for (NSString *key in dict.allKeys) {
        
        id ite = [dict objectForKey:key];
        if ([ite isKindOfClass:[NSArray class]]) {
            continue;
        }
        
        [sStr appendString:[NSString stringWithFormat:@"\
                            \n  if ([key isEqualToString:@\"%@\"]){\
                            \n      self.%@ = value;\
                            \n  }",key,key]];
    }

    if (sStr.length > 0) {
        NSString *svalue = [NSString stringWithFormat:
                            @"\
                            \n-(void)setValue:(id)value forKey:(NSString *)key{\
                            \n  %@\
                            \n  else{\
                            \n      [super setValue:value forKey:key];\
                            \n  }\
                            \n}",sStr];
        return svalue;
    }
    return @"";
}

- (NSString *)yyi_propertyMapWith:(NSDictionary *)dict{
    NSMutableString *sStr = [NSMutableString new];

    for (NSString *key in dict.allKeys) {
        
        id ite = [dict objectForKey:key];
        if ([ite isKindOfClass:[NSArray class]]) {
            continue;
        }
        
        [sStr appendString:[NSString stringWithFormat:@"\
                            \n      @\"%@\":@\"%@\",",key,key]];
    }

    return [NSString stringWithFormat:@"\n+(NSDictionary<NSString *,NSString *> *)propertyNameMappingDict{\
            \n  return @{%@};\
            \n}",sStr];
}



@end
